<?php

namespace app\admin\controller;

use app\admin\model\User;
use app\api\model\ProjectAssign;
use app\api\model\ProjectLogCheckdetail;
use app\api\model\UserMoneyLog;
use app\common\controller\Backend;
use Exception;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;
use app\api\model\User as UserModel;
use think\Log;

/**
 * 项目日志管理
 *
 * @icon fa fa-circle-o
 */
class ProjectLog extends Backend
{
    
    /**
     * ProjectLog模型对象
     * @var \app\admin\model\ProjectLog
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\ProjectLog;
        $checkStatus = [
            '0' => '待审核',
            '1' => '审核通过',
            '2' => '拒绝'
        ];
        $this->assignconfig('checkStatus', (object)$checkStatus);
    }
    
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                ->where($where)
                ->order($sort, $order)
                ->count();

            $list = $this->model
                ->where($where)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();

            $list = collection($list)->toArray();
            if ($list) {
                foreach ($list as &$listVal) {
                    $user = User::findInfoByCondition(['id' => $listVal['uid']]);
                    $project = \app\admin\model\Project::findInfoByCondition(['id' => $listVal['project_id']]);
                    $listVal['hua_name'] = $user && $user['hua_name'] ? $user['hua_name'] : '';
                    $listVal['project_name'] = $project && $project['pname'] ? $project['pname'] : '';
                }
            }

            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);
                $result = false;

                //防止接口1s重复调用
                $this->checkAdminRequestFrequently("cklog{$ids}");

                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                        $row->validateFailException(true)->validate($validate);
                    }
                    $log = \app\api\model\ProjectLog::findInfoByCondition(['id' => $ids], 1);
                    if ($log['check_status'] == 1) {
                        throw new \Exception(__('不能重复操作！'));
                    }

                    $project = \app\admin\model\Project::findInfoByCondition(['id' => $log['project_id']]);
                    if (!$project) {
                        throw new \Exception(__('项目不存在！'));
                    }
                    if ($project['is_end'] == 1) {
                        throw new \Exception(__('项目已结束！'));
                    }

                    // 审核状态
                    $status = isset($params['check_status']) ? $params['check_status'] : 0;

                    if ($status == 1) { // 审核通过
                        $params['pass_time'] = time();
                    } elseif ($status == 2) {   //审核拒绝
                        $params['refuse_time'] = time();
                    }

                    $result = $row->allowField(true)->save($params);

                    if ($status != 0) {
                        // 工时乘以了100
                        $hour = intval(((int)$log['time_end'] - (int)$log['time_start']) / 3600 * 100);
                        $assign = ProjectAssign::findInfoByCondition(['id' => $log['project_assign_id'], 'uid' => $log['uid'], 'project_id' => $log['project_id']]);
                        if ($assign) {
                            if ($status == 1) { // 审核通过
                                // 更新已工作时长
                                $row = [
                                    'has_work_hour' => Db::raw("has_work_hour + {$hour}"),
                                    'uncheck_work_hour' => Db::raw("uncheck_work_hour - {$hour}")
                                ];
                                ProjectAssign::saveData(['id' => $assign['id']], $row);
                            } elseif ($status == 2) {   //审核拒绝
                                // 更新拒绝工作时长
                                $row = [
                                    'refuse_work_hour' => Db::raw("refuse_work_hour + {$hour}"),
                                    'uncheck_work_hour' => Db::raw("uncheck_work_hour - {$hour}")
                                ];
                                ProjectAssign::saveData(['id' => $assign['id']], $row);
                            }
                        }

                        if ($status == 1 && $assign['employ_price'] > 0) { // 审核通过, 并且分配时选择的是计费，并且有雇佣价格，则计算价格
                            //需要计算价格的工时处理
                            $jsHour = ProjectAssign::formatHours($hour);
                            if ($jsHour > 0) {  //有工时
                                //查询是否已经给过钱
                                $logCheck = ProjectLogCheckdetail::findInfoByCondition(['project_log_id' => $log['id']]);
                                if ($logCheck) {
                                    Db::rollback();
                                    throw new \Exception(__('不能重复操作！'));
                                }
                                $reciveUser = UserModel::findInfoByCondition(['id' => $log['uid']], 1);
                                if  (!$reciveUser) {
                                    Db::rollback();
                                    throw new \Exception(__('日志用户不存在！'));
                                }
                                $amount = ((int)$reciveUser['wage']) * $jsHour;
                                //企业需要扣钱的金额
                                $companyAmunt = $assign['employ_price'] * $jsHour;
                                if ($companyAmunt > 0 && $amount > 0) {  // 有金额
                                    $project = \app\api\model\Project::findInfoByCondition(['id' => $log['project_id']]);
                                    if (!$project || !$project['puid']) {
                                        Db::rollback();
                                        throw new \Exception(__('项目用户不存在！'));
                                    }

                                    $sendUser = UserModel::findInfoByCondition(['id' => $project['puid']], 1);
                                    if  (!$sendUser) {
                                        Db::rollback();
                                        throw new \Exception(__('项目用户不存在！'));
                                    }
                                    //检测企业余额是否充足
                                    if ($sendUser['money'] < $companyAmunt) {
                                        Db::rollback();
                                        throw new \Exception(__('余额不足！'));
                                    }
                                    $logCheckAdd = [
                                        'project_log_id' => $log['id'],
                                        'project_id' => $log['project_id'],
                                        'receive_uid' => $log['uid'],
                                        'send_uid' => $sendUser['id'],
                                        'amount' => $amount,
                                        'hours' => $hour,
                                        'operate_uid' => $this->auth->id
                                    ];
                                    $logCheckId = ProjectLogCheckdetail::addRecord($logCheckAdd);
                                    if (!$logCheckId) {
                                        Db::rollback();
                                        throw new \Exception(__('审核失败！'));
                                    }
                                    $userMoneyData = [];
                                    if ($assign['is_charge'] == 1) {    //如果项目分配的时候计费
                                        // 增加日志用户金额
                                        $userData = [
                                            'money' => (float)(sprintf('%.2f', $reciveUser['money']) + $amount)
                                        ];
                                        UserModel::saveData($reciveUser['id'], $userData);
                                        //增加金额变动明细
                                        $userMoneyData = [
                                            'user_id' => $reciveUser['id'],
                                            'money' => $amount,
                                            'before' => $reciveUser['money'],
                                            'after' => $userData['money'],
                                            'memo' => "项目[{$log['project_id']}]进账"
                                        ];
                                        $userMoneyId = UserMoneyLog::addRecord($userMoneyData);
                                        if (!$userMoneyId) {
                                            Db::rollback();
                                            throw new \Exception(__('写入失败！'));
                                        }
                                    }

                                    //减去企业金额
                                    if ($sendUser['id'] == $reciveUser['id']) { // 自己给自己操作
                                        if (isset($userMoneyData) && $userMoneyData) {
                                            $beforeMoney = $userMoneyData['after'];
                                            $userData = [
                                                'money' => (float)(sprintf('%.2f', $userMoneyData['after']) - $companyAmunt)
                                            ];
                                        } else {
                                            $beforeMoney = $sendUser['money'];
                                            $userData = [
                                                'money' => (float)(sprintf('%.2f', $sendUser['money']) - $companyAmunt)
                                            ];
                                        }
                                        UserModel::saveData($sendUser['id'], $userData);
                                        //增加金额变动明细
                                        $userMoneyData = [
                                            'user_id' => $sendUser['id'],
                                            'money' => $companyAmunt,
                                            'before' => $beforeMoney,
                                            'after' => $userData['money'],
                                            'memo' => "项目[{$log['project_id']}]出账"
                                        ];
                                    } else {
                                        $userData = [
                                            'money' => (float)(sprintf('%.2f', $sendUser['money']) - $companyAmunt)
                                        ];
                                        UserModel::saveData($sendUser['id'], $userData);
                                        //增加金额变动明细
                                        $userMoneyData = [
                                            'user_id' => $sendUser['id'],
                                            'money' => $companyAmunt,
                                            'before' => $sendUser['money'],
                                            'after' => $userData['money'],
                                            'memo' => "项目[{$log['project_id']}]出账"
                                        ];
                                    }

                                    if ($userMoneyData) {
                                        $userMoneyId = UserMoneyLog::addRecord($userMoneyData);
                                        if (!$userMoneyId) {
                                            Db::rollback();
                                            throw new \Exception(__('写入失败！'));
                                        }
                                    }

                                    unset($userMoneyData);
                                    unset($userData);
                                    unset($logCheckAdd);
                                    unset($sendUser);
                                }
                                unset($reciveUser);
                            }
                        }
                    }

                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        if (isset($row['time_start']) && $row['time_start']) {
            $row['time_start'] = date('Y-m-d H:i:s', $row['time_start']);
        }
        if (isset($row['time_end']) && $row['time_end']) {
            $row['time_end'] = date('Y-m-d H:i:s', $row['time_end']);
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

}
